package Test;

import java.io.ByteArrayInputStream;
import java.util.ArrayList;

import Expression.Expression;
import Expression.ExpressionValue;
import Service.Variable;
import junit.framework.TestCase;

/**
 * @author cyye
 *
 */
public class ExpressionTestCase extends TestCase {

	public ExpressionTestCase(String name) {
		super(name);
	}

	protected void setUp() throws Exception {
		super.setUp();
	}

	protected void tearDown() throws Exception {
		super.tearDown();
	}

	private String expr1 = " a3:=a1+a2;a6:=a4;a9:= a7 + a8*2;a12:= a10 && a11 ; ";
	private String expr2 = "a12:= !a11 && a10;";
	private String expr3 = "a9:= (a7 + a8)*2; a3:=(3 + a1/a2);a6:=test;";
	private String expr4 = "a9:= (a7 - a8)*2 + a2; a7:=(3*a7  + a1/a2) - a9; a11:=a9 < a7 && ! a4==string2;";
	private String expr5 = "(a7 - a8)*2 + a2 >= (3*a7  + a1/a2) - 15.0 || a10 && !a11";
	private String expr6 = "(a7 - a8)*2 - a2 * (3*a7  + a1/a2) - 15.0";
	private String expr7 = "a3:=a1;a3:=a3/a2;a3:=a1+a2+a3;";
	private String expr8 = "a12:=false;a3:=(a1+a2*2)/a1/2;";
	private String expr9 = "true";
	private String expr10 = "";

	private ArrayList<Variable> initVariables() {
		ArrayList<Variable > variables = new ArrayList<Variable >(); 
		
		Variable v1 = new Variable();
		v1.setName("a1");
		v1.setType(Variable.INTEGER);
		v1.setValue(new Integer(10));
		variables.add(v1);

		Variable v2 = new Variable();
		v2.setName("a2");
		v2.setType(Variable.INTEGER);
		v2.setValue(new Integer(5));
		variables.add(v2);

        Variable v3 = new Variable();
	    v3.setName("a3");
		v3.setType(Variable.INTEGER);
		v3.setValue(null);
		variables.add(v3);
		
		Variable v4 = new Variable();
		v4.setName("a4");
		v4.setType(Variable.STRING);
		v4.setValue("String1");
		variables.add(v4);

		Variable v5 = new Variable();
		v5.setName("a5");
		v5.setType(Variable.STRING);
		v5.setValue("String2");
		variables.add(v5);

        Variable v6 = new Variable();
	    v6.setName("a6");
		v6.setType(Variable.STRING);
		v6.setValue(null);
		variables.add(v6);		
		
		Variable v7 = new Variable();
		v7.setName("a7");
		v7.setType(Variable.FLOAT);
		v7.setValue(new Float(10.0));
		variables.add(v7);

		Variable v8 = new Variable();
		v8.setName("a8");
		v8.setType(Variable.FLOAT);
		v8.setValue(new Float(5.0));
		variables.add(v8);

        Variable v9 = new Variable();
	    v9.setName("a9");
		v9.setType(Variable.FLOAT);
		v9.setValue(null);
		variables.add(v9);		
		
		Variable v10 = new Variable();
		v10.setName("a10");
		v10.setType(Variable.BOOLEAN);
		v10.setValue(new Boolean(true));
		variables.add(v10);

		Variable v11 = new Variable();
		v11.setName("a11");
		v11.setType(Variable.BOOLEAN);
		v11.setValue(new Boolean(false));
		variables.add(v11);

        Variable v12 = new Variable();
	    v12.setName("a12");
		v12.setType(Variable.BOOLEAN);
		v12.setValue(null);
		variables.add(v12);	
		
		return variables;
	}
	
	/*
	public void testExpr10() {	   
		   //ExpressionValue value = null;	
		     
		   ArrayList<Variable> variables = initVariables();	    
		   ByteArrayInputStream in = new ByteArrayInputStream(expr10.getBytes());	   
		   Expression parser = new Expression(in);
		   ExpressionValue value;
		   
		   try{
			   value = parser.CalculateExpression(variables);	
			   
			   
			   assertNotNull(value);
			   //assertEquals(value.type, Variable.FLOAT);		   			   
			   //assertEquals(((Float)value.value).floatValue(), -165.0, 0.000001);
			   
			   
		   } catch (Exception e) {
		        System.out.println("NOK.");
		        System.out.println(e);
		        assertTrue(false);
		        
		   } catch (Error e) {
		        System.out.println("Oops.");
		        System.out.println(e);
		        assertTrue(false);
		  }	  	  	 
	}
	*/
	public void testExpr9() {	   
		   //ExpressionValue value = null;	
		     
		   ArrayList<Variable> variables = initVariables();	    
		   ByteArrayInputStream in = new ByteArrayInputStream(expr9.getBytes());	   
		   Expression parser = new Expression(in);
		   ExpressionValue value;
		   
		   try{
			   value = parser.CalculateExpression(variables);	
			   
			   
			   assertNotNull(value);
			   assertEquals(value.type, Variable.BOOLEAN);		   			   
			   assertEquals(((Boolean)value.value).booleanValue(), true);
			   
			   
		   } catch (Exception e) {
		        System.out.println("NOK.");
		        System.out.println(e);
		        assertTrue(false);
		        
		   } catch (Error e) {
		        System.out.println("Oops.");
		        System.out.println(e);
		        assertTrue(false);
		  }	  	  	 
	}
	
	public void testExpr8() {	   
		   //ExpressionValue value = null;	
		     
		   ArrayList<Variable> variables = initVariables();	    
		   ByteArrayInputStream in = new ByteArrayInputStream(expr8.getBytes());	   
		   Expression parser = new Expression(in);
		   
		   try{
			   parser.AssignExpression(variables);	
			   
			   Variable vb = getVariable(variables, "a3");
			   assertNotNull(vb);
			   assertEquals(vb.getType(), Variable.INTEGER);		   
			   assertEquals(((Integer)vb.getValue()).intValue(), 1);		   
			   			  
			   vb = getVariable(variables, "a12");
			   assertNotNull(vb);
			   assertEquals(vb.getType(), Variable.BOOLEAN);		   
			   assertEquals(((Boolean)vb.getValue()).booleanValue(), false);	
			   
		   } catch (Exception e) {
		        System.out.println("NOK.");
		        System.out.println(e);
		        assertTrue(false);
		        
		   } catch (Error e) {
		        System.out.println("Oops.");
		        System.out.println(e);
		        assertTrue(false);
		  }	  	  	 
	}
	
	public void testExpr7() {	   
		   //ExpressionValue value = null;	
		     
		   ArrayList<Variable> variables = initVariables();	    
		   ByteArrayInputStream in = new ByteArrayInputStream(expr7.getBytes());	   
		   Expression parser = new Expression(in);
		   
		   try{
			   parser.AssignExpression(variables);	
			   
			   Variable vb = getVariable(variables, "a3");
			   assertNotNull(vb);
			   assertEquals(vb.getType(), Variable.INTEGER);		   
			   assertEquals(((Integer)vb.getValue()).intValue(), 17);		   
			   			  
			   
		   } catch (Exception e) {
		        System.out.println("NOK.");
		        System.out.println(e);
		        assertTrue(false);
		        
		   } catch (Error e) {
		        System.out.println("Oops.");
		        System.out.println(e);
		        assertTrue(false);
		  }	  	  	 
		}
	
	public void testExpr6() {	   
		   //ExpressionValue value = null;	
		     
		   ArrayList<Variable> variables = initVariables();	    
		   ByteArrayInputStream in = new ByteArrayInputStream(expr6.getBytes());	   
		   Expression parser = new Expression(in);
		   ExpressionValue value;
		   
		   try{
			   value = parser.CalculateExpression(variables);	
			   
			   
			   assertNotNull(value);
			   assertEquals(value.type, Variable.FLOAT);		   			   
			   assertEquals(((Float)value.value).floatValue(), -165.0, 0.000001);
			   
			   
		   } catch (Exception e) {
		        System.out.println("NOK.");
		        System.out.println(e);
		        assertTrue(false);
		        
		   } catch (Error e) {
		        System.out.println("Oops.");
		        System.out.println(e);
		        assertTrue(false);
		  }	  	  	 
		}
	
	
	public void testExpr5() {	   
		   //ExpressionValue value = null;	
		     
		   ArrayList<Variable> variables = initVariables();	    
		   ByteArrayInputStream in = new ByteArrayInputStream(expr5.getBytes());	   
		   Expression parser = new Expression(in);
		   ExpressionValue value;
		   
		   try{
			   value = parser.CalculateExpression(variables);	
			   
			   
			   assertNotNull(value);
			   assertEquals(value.type, Variable.BOOLEAN);		   			   
			   assertEquals(value.value, true);
			   
			   
		   } catch (Exception e) {
		        System.out.println("NOK.");
		        System.out.println(e);
		        assertTrue(false);
		        
		   } catch (Error e) {
		        System.out.println("Oops.");
		        System.out.println(e);
		        assertTrue(false);
		  }	  	  	 
		}
	
	public void testExpr4() {	   
		   //ExpressionValue value = null;	
		     
		   ArrayList<Variable> variables = initVariables();	    
		   ByteArrayInputStream in = new ByteArrayInputStream(expr4.getBytes());	   
		   Expression parser = new Expression(in);
		   
		   try{
			   parser.AssignExpression(variables);	
			   
			   Variable vb = getVariable(variables, "a9");
			   assertNotNull(vb);
			   assertEquals(vb.getType(), Variable.FLOAT);		   
			   assertEquals(((Float)vb.getValue()).floatValue(), 15.0, 0.000001);		   
			   
			   vb = getVariable(variables, "a7");
			   assertNotNull(vb);
			   assertEquals(vb.getType(), Variable.FLOAT);		   
			   assertEquals(((Float)vb.getValue()).floatValue(), 17.0, 0.000001);
			   
			   	  
			   vb = getVariable(variables, "a11");
			   assertNotNull(vb);
			   assertEquals(vb.getType(), Variable.BOOLEAN);	
			   assertEquals(((Boolean)vb.getValue()).booleanValue(), true);
			   
			   
		   } catch (Exception e) {
		        System.out.println("NOK.");
		        System.out.println(e);
		        assertTrue(false);
		        
		   } catch (Error e) {
		        System.out.println("Oops.");
		        System.out.println(e);
		        assertTrue(false);
		  }	  	  	 
		}
	
	public void testExpr3() {	   
	   //ExpressionValue value = null;	
	     
	   ArrayList<Variable> variables = initVariables();	    
	   ByteArrayInputStream in = new ByteArrayInputStream(expr3.getBytes());	   
	   Expression parser = new Expression(in);
	   
	   try{
		   parser.AssignExpression(variables);	
		   
		   Variable vb = getVariable(variables, "a9");
		   assertNotNull(vb);
		   assertEquals(vb.getType(), Variable.FLOAT);		   
		   assertEquals(((Float)vb.getValue()).floatValue(), 30.0, 0.000001);		   
		   
		   vb = getVariable(variables, "a3");
		   assertNotNull(vb);
		   assertEquals(vb.getType(), Variable.INTEGER);		   
		   assertEquals(((Integer)vb.getValue()).intValue(), 5);
		   
		   vb = getVariable(variables, "a6");
		   assertNotNull(vb);
		   assertEquals(vb.getType(), Variable.STRING);		   
		   assertEquals(vb.getValue(),"test");
		   
		   
	   } catch (Exception e) {
	        System.out.println("NOK.");
	        System.out.println(e);
	        assertTrue(false);
	        
	   } catch (Error e) {
	        System.out.println("Oops.");
	        System.out.println(e);
	        assertTrue(false);
	  }	  	  	 
	}
	
	public void testExpr2() {	   
		   //ExpressionValue value = null;	
		     
		   ArrayList<Variable> variables = initVariables();	    
		   ByteArrayInputStream in = new ByteArrayInputStream(expr2.getBytes());	   
		   Expression parser = new Expression(in);
		   
		   try{
			   parser.AssignExpression(variables);	
			   
			   Variable vb = getVariable(variables, "a12");
			   assertNotNull(vb);
			   assertEquals(vb.getType(), Variable.BOOLEAN);		   
			   assertEquals(((Boolean)vb.getValue()).booleanValue(), true);			   			   			   
			   
		   } catch (Exception e) {
		        System.out.println("NOK.");
		        System.out.println(e);
		        assertTrue(false);
		        
		   } catch (Error e) {
		        System.out.println("Oops.");
		        System.out.println(e);
		        assertTrue(false);
		  }	  	  	 
	}
	
	public void testExpr1() {	   
		   //ExpressionValue value = null;	
		     
		   ArrayList<Variable> variables = initVariables();	    
		   ByteArrayInputStream in = new ByteArrayInputStream(expr1.getBytes());	   
		   Expression parser = new Expression(in);
		   
		   try{
			   parser.AssignExpression(variables);	
			   
			   Variable vb = getVariable(variables, "a3");
			   assertNotNull(vb);
			   assertEquals(vb.getType(), Variable.INTEGER);		   
			   assertEquals(((Integer)vb.getValue()).intValue(), 15);
			   
			   vb = getVariable(variables, "a6");
			   assertNotNull(vb);
			   assertEquals(vb.getType(), Variable.STRING);		   
			   assertEquals(vb.getValue(), "String1");
			   
			   vb = getVariable(variables, "a9");
			   assertNotNull(vb);
			   assertEquals(vb.getType(), Variable.FLOAT);		   
			   assertEquals(((Float)vb.getValue()).floatValue(), 20.0, 0.000001);
			   
			   vb = getVariable(variables, "a12");
			   assertNotNull(vb);
			   assertEquals(vb.getType(), Variable.BOOLEAN);		   
			   assertEquals(((Boolean)vb.getValue()).booleanValue(), false);
			   
		   } catch (Exception e) {
		        System.out.println("NOK.");
		        System.out.println(e);
		        assertTrue(false);
		        
		   } catch (Error e) {
		        System.out.println("Oops.");
		        System.out.println(e);
		        assertTrue(false);
		  }	  	  	 
	}	
	
	private Variable getVariable(ArrayList<Variable> variables, String name) {	    
	    for(int i=0;i<variables.size();i++) {
	    	if(name.equals(variables.get(i).getName())) {
	    		return variables.get(i);
	    	}
	    }
	    return null;
	}					
	
}
